#pragma once

#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <iomanip>
#include <sstream>
#include <cmath>
#include <stdexcept>
#include <unordered_map>
#include <ranges>
#include <initializer_list>
#include <mutex>
#include <unordered_set>
#include <regex>

#include <nlohmann/json.hpp>
#include <curl/curl.h>

#include "curlclient.h"
#include "config.h"

#pragma pack(push, 1) // 确保结构体按1字节对齐
struct Field {
    uint8_t functionBit;
    uint8_t digitBit;
    uint8_t decimalBit;
};

struct Compass {
    uint8_t header;
    uint8_t dataLength;
    uint8_t addressCode;
    uint8_t commandId;

    Field pitch;
    Field roll;
    Field heading;
    uint8_t checksum;
};
#pragma pack(pop)

#pragma pack(push, 1)// 确保结构体按1字节对齐

struct Guidance {
    uint8_t head1;
    uint8_t head2;
    uint8_t dataLength;       // 帧长度  Uchar   1  ——  0xA0  ——
    uint8_t addressCode;      // 帧ID    Uchar   1  ——  0xA1  ——

    uint32_t powerOnTime;      // 上电时间/GPS周秒  Uint  4  s  0～  1E-03
    uint32_t navTime;          // 导航时间        Uint  4  s  0～  1E-03
    uint32_t statusWord;       // 状态字          Uint  4  ——  ——  ——
    uint32_t faultWord;        // 故障字          Uint  4  ——  ——  ——

    int32_t inertiaPitch;      // 惯性俯仰角      int   4  deg  ±90  1E-06
    int32_t inertiaRoll;       // 惯性滚动角      int   4  deg  ±180 1E-06
    int32_t inertiaHeading;    // 惯性航向角      int   4  deg  0~360  1E-06
    int32_t inertiaLongitude;  // 惯性经度        int   4  deg  ±180 1E-07
    int32_t inertiaLatitude;   // 惯性纬度        int   4  deg  ±90  1E-07
    int32_t inertiaHeight;     // 惯性高度        int   4  m  ——  1E-03
    int32_t inertiaEastSpeed;  // 惯性东速        int   4  m/s  ——  1E-04
    int32_t inertiaNorthSpeed; // 惯性北速        int   4  m/s  ——  1E-04
    int32_t inertiaSkySpeed;   // 惯性天速        int   4  m/s  ——  1E-04
    float xAxisAngularSpeedEncoded;
    float yAxisAngularSpeedEncoded;
    float zAxisAngularSpeedEncoded;
    float xAxisAccelerationEncoded;
    float yAxisAccelerationEncoded;
    float zAxisAccelerationEncoded;
    int32_t combinedPitch;     // 组合俯仰角      int   4  deg  ±90  1E-06
    int32_t combinedRoll;      // 组合滚动角      int   4  deg  ±180 1E-06
    int32_t combinedHeading;   // 组合航向角      int   4  deg  0~360  1E-06
    int32_t combinedLongitude; // 组合经度        int   4  deg  ±180 1E-07
    int32_t combinedLatitude;  // 组合纬度        int   4  deg  ±90  1E-07
    int32_t combinedHeight;    // 组合高度        int   4  m  ——  1E-03
    int32_t combinedEastSpeed; // 组合东速        int   4  m/s  ——  1E-04
    int32_t combinedNorthSpeed;// 组合北速        int   4  m/s  ——  1E-04
    int32_t combinedSkySpeed;  // 组合天速        int   4  m/s  ——  1E-04
    uint32_t ppsTime;          // PPS时间        Uint  4  s  0～  1E-03
    uint32_t satelliteTime;    // 卫星时间        Uint  4  ——  0～  ——
    int32_t satelliteLongitude;// 卫星经度        int   4  deg  ±180 1E-07
    int32_t satelliteLatitude; // 卫星纬度        int   4  deg  ±90  1E-07
    int32_t satelliteHeight;   // 卫星高度        int   4  m  ——  1E-03
    int32_t satelliteEastSpeed;// 卫星东速        int   4  m/s  ——  1E-04
    int32_t satelliteNorthSpeed;// 卫星北速       int   4  m/s  ——  1E-04
    int16_t satelliteSkySpeed; // 卫星天速       short 2  m/s  ——  1E-02
    uint8_t positioningStatus; // 定位状态       Uchar 1  ——  ——  ——
    uint8_t availableSatellites; // 可用星数   Uchar 1  ——  0～  1E+00
    int16_t elevationAnomaly;  // 高程异常       short 2  m      1E-02
    uint16_t gpsWeek;          // GPS周         Ushort 2  ——  0～  1
    uint16_t hdopValue;        // HDOP值        Ushort 2  ——  ——  1E-02
    uint16_t vdopValue;        // VDOP值        Ushort 2  ——  ——  1E-02

    int8_t temperature;        // 温度           char  1  ——  -128~127  1
    uint8_t humidity;          // 湿度           Uchar 1  ——  0～100  0.5
    uint8_t bak;               // bak            Uchar 1  ——  ——  ——
    uint8_t checksum;          // 校验字         Uchar 1  前面所有字节的异或
};

#pragma pack(pop)

#pragma pack(push, 1)
struct Seatrac {
    // 基本信息（偏移0-5，文档定义）
    uint8_t CmdId;                      // 偏移0（1字节）
    uint8_t OutputFlags;                // 偏移1（1字节）
    uint32_t Timestamp_ms;              // 偏移2（4字节）

    // 预留字段（偏移6-9，文档要求必须保留，4字节）
    uint8_t reserved[4];                // 偏移6-9，未定义内容

    // 环境数据（偏移10-23，文档定义）
    uint16_t EnvironmentSupply;         // 偏移10（2字节）
    int16_t EnvironmentTemperature;     // 偏移12（2字节）
    int32_t EnvironmentPressure;        // 偏移14（4字节）
    int32_t EnvironmentDepth;           // 偏移18（4字节）
    uint16_t EnvironmentVos;            // 偏移22（2字节）

    // 姿态数据（偏移24-29，文档定义）
    int16_t AttitudeYaw;                // 偏移24（2字节）
    int16_t AttitudePitch;              // 偏移26（2字节）
    int16_t AttitudeRoll;               // 偏移28（2字节）

    // 磁校准数据（偏移30-37，文档定义）
    uint8_t MagCalBuf;                  // 偏移30（1字节）
    uint8_t MagCalValid;                // 偏移31（1字节，文档用UINT8表示布尔值）
    uint32_t MagCalAge;                 // 偏移32（4字节）
    uint8_t MagCalFit;                  // 偏移36（1字节）

    // 加速度限幅（偏移37-48，文档定义）
    int16_t AccLimMinX;                 // 偏移37（2字节）
    int16_t AccLimMinY;                 // 偏移39（2字节）
    int16_t AccLimMinZ;                 // 偏移41（2字节）
    int16_t AccLimMaxX;                 // 偏移43（2字节）
    int16_t AccLimMaxY;                 // 偏移45（2字节）
    int16_t AccLimMaxZ;                 // 偏移47（2字节）

    // 原始传感器数据（偏移49-66，文档定义）
    int16_t AccRawX;                    // 偏移49（2字节）
    int16_t AccRawY;                    // 偏移51（2字节）
    int16_t AccRawZ;                    // 偏移53（2字节）
    int16_t MagRawX;                    // 偏移55（2字节）
    int16_t MagRawY;                    // 偏移57（2字节）
    int16_t MagRawZ;                    // 偏移59（2字节）
    int16_t GyroRawX;                   // 偏移61（2字节）
    int16_t GyroRawY;                   // 偏移63（2字节）
    int16_t GyroRawZ;                   // 偏移65（2字节）

    // 补偿后数据（偏移67-102，文档定义）
    float AccCompX;                     // 偏移67（4字节）
    float AccCompY;                     // 偏移71（4字节）
    float AccCompZ;                     // 偏移75（4字节）
    float MagCompX;                     // 偏移79（4字节）
    float MagCompY;                     // 偏移83（4字节）
    float MagCompZ;                     // 偏移87（4字节）
    float GyroCompX;                    // 偏移91（4字节）
    float GyroCompY;                    // 偏移95（4字节）
    float GyroCompZ;                    // 偏移99（4字节）

    // CRC校验（偏移103-104，文档定义）
    uint8_t CRC16_lo;                   // 偏移103（1字节）
    uint8_t CRC16_hi;                   // 偏移104（1字节）
};
#pragma pack(pop)

#pragma pack(push, 1)
struct Body {
    uint8_t id;
    uint8_t len;
    std::vector<uint8_t> item;
};

struct Posture {
    uint8_t head1;
    uint8_t head2;
    uint8_t tid1;
    uint8_t tid2;
    std::vector<Body> bodies;
    uint8_t ck1;
    uint8_t ck2;
};
#pragma pack(pop)

#pragma pack(push, 1) // 确保结构体按1字节对齐

struct Humiture {
    uint8_t station;
    uint8_t code;
    uint8_t length;
    uint8_t tem_high;
    uint8_t tem_low;
    uint8_t hum_high;
    uint8_t hum_low;
    uint16_t cyc;
};

#pragma pack(pop)

enum class BID_E {
    BEACON_ALL = 0x00,
    BEACON_ID_1 = 0x01,
    BEACON_ID_2 = 0x02
};

struct NAV_QUERY_T {
    uint8_t qry_depth: 1;
    uint8_t qry_supply : 1;
    uint8_t qry_temp : 1;
    uint8_t qry_attitude : 1;
    uint8_t reserved_4_6 : 3;
    uint8_t qry_data : 1;
};

struct ACOFIX_T {
    BID_E dest_id;
    BID_E src_id;
    uint8_t flags;
    uint8_t msg_type;
    int16_t attitude_yaw;
    int16_t attitude_pitch;
    uint16_t depth_local;
    uint16_t vos;
    int16_t rssi;
};

enum NAV_CID_E {
    CID_NAV_QUERY_SEND = 0x50,
    CID_NAV_QUERY_RESP = 0x52
};

struct NAV_Send_Struct {
    char sync_char;
    NAV_CID_E msg_id;
    BID_E dest_id;
    NAV_QUERY_T query_flags;
    uint8_t packet_len;
    std::vector<uint8_t> packet_data = { 29 };
    uint16_t checksum;
    std::vector<uint8_t> end_char = {2};
};

struct NAV_Receive_Struct {
    char sync_char;
    NAV_CID_E msg_id;
    ACOFIX_T aco_fix;
    NAV_QUERY_T query_flags;
    uint8_t local_flag;
    uint16_t checksum;
    std::vector<uint8_t> end_char = {2};
};

void post_sensor_data(const std::string& name, const std::string& url);

void post_timeout_data(const std::string& name, const std::string& url);

std::string transfer_json(const std::string& name, const std::vector<double>& data);

nlohmann::json transfer_compass_json(const std::vector<double>& data);

nlohmann::json transfer_depth_json(const std::vector<double>& data);

nlohmann::json transfer_dvl_json(const std::vector<double>& data);

nlohmann::json transfer_guidance_json(const std::vector<double>& data);

nlohmann::json transfer_gps_json(const std::vector<double>& data);

nlohmann::json transfer_posture_json(const std::vector<double>& data);

nlohmann::json transfer_humiture_json(const std::vector<double>& data);

nlohmann::json transfer_seatrac_json(const std::vector<double>& data);

uint8_t calCompassCk(const uint8_t* data, int len);

std::pair<uint8_t, uint8_t> calPostureCk(const uint8_t* data, int len);

uint8_t calGuidanceCk(const uint8_t* data, int len);

uint16_t calSeatracCk(const uint8_t* data, int len);

uint8_t calGPSCK(const std::string& data, size_t start, size_t end);

uint16_t calHumitureCk(const uint8_t* data, int len);

double convertCompassFe(const Field& field);

std::vector<double> parse_sensor_data(const std::string& name,const std::string& data);

std::vector<double> parseCompass(const std::string& data);

std::vector<double> parseDepth(const std::string& data);

std::vector<double> parseGuidance(const std::string& data);

std::pair<std::string, std::vector<double>> parseDVL(const std::string& data);

std::vector<double> parsePosture(const std::string& data);

std::vector<double> parseSeatrac(const std::string& data);

std::vector<double> parseGPS(const std::string& data);

std::vector<double> parseHumiture(const std::string& data);

std::string generate_csv_header(const std::vector<std::string>& fields);

std::string get_header(const std::string& name);

std::string get_last_message(const std::string& name, const std::string& data);

std::string getLastCompass(const std::string& data);

std::string getLastDepth(const std::string& data);

std::string getLastGuidance(const std::string& data);

std::string getLastDVL(const std::string& data);

std::string getLastPosture(const std::string& data);

std::string getLastSeatrac(const std::string& data);

std::string getLastGPS(const std::string& data);

std::string getLastHumiture(const std::string& data);

std::string hexStringToBytes(const std::string& hex_str);

std::string send_remote_x010_data();

std::vector<double> receive_remote_x010_data(const std::string& data);

int64_t move(const uint8_t* data, int step);

const double commonFactor = 0.000001;

std::vector<std::string> splitDVLList(const std::string& line);

std::vector<std::vector<std::string>> constructDVLList(const std::string& data);

std::vector<uint8_t> hexStringToByteses(const std::string& hex);

static inline int hexNibble(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
    if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
    return -1;
}

uint8_t calculateXOR(const uint8_t* data, int len);

double stringToDouble(const std::string& str);

double strToDouble(const std::string& str);

uint8_t hexStrToValue(const std::string& hexStr);

const std::string COMPASS = "compass";
const std::string DEPTH = "depth";
const std::string DVL = "dvl";
const std::string GPS = "gps";
const std::string POSTURE = "posture";
const std::string GUIDANCE = "guidance";
const std::string SEATRAC = "seatrac";
const std::string HUMITURE = "humiture";

